package com.jc.order.service.impl;

import cn.hutool.core.util.StrUtil;
import com.jc.constant.OperationTypeEnum;
import com.jc.order.common.ValidatorUtil;
import com.jc.order.constant.ChangeReasonCodeEnum;
import com.jc.order.constant.CountryEnum;
import com.jc.order.constant.ProductCategoryEnum;
import com.jc.order.constant.ProvinceEnum;
import com.jc.order.constant.QuotaApplyConstants;
import com.jc.order.dto.EciCustomerQuotaApplyDTO;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 限额申请表校验工具
 */
public class EciQuotaApplyValidator {


    /**
     * 校验限额申请表对象
     *
     * @param apply 待校验的对象
     * @return 包含所有错误信息的列表，空列表表示校验通过
     */
    public static List<String> validate(EciCustomerQuotaApplyDTO apply) {
        List<String> errors = new ArrayList<>();


        initApply(apply);

//        determineBusinessType(apply, errors);

        // 基础信息校验
        validateBaseInfo(apply, errors);

        // 买方信息校验
        validateBuyerInfo(apply, errors);

        // 限额信息校验
        validateQuotaInfo(apply, errors);

        // 信用证相关校验
        if (QuotaApplyConstants.BusinessType.LC.equals(apply.getBusinessType())) {
            validateLcInfo(apply, errors);
        }

        // 历史交易信息校验
        validateTransactionHistory(apply, errors);

        // 其他业务信息校验
        validateBusinessInfo(apply, errors);

        // 公共字段长度校验
        validateFieldLengths(apply, errors);

        return errors;
    }


    public static void initApply(EciCustomerQuotaApplyDTO apply) {
//        String simpleUUID = IdUtil.simpleUUID();
//        apply.setSender("PXAM202533010664F00003");
//        apply.setReceiver("PICC");
//        apply.setMessageType("GOMS_QuotaApply");
//        apply.setUsageIndicator("P");
//        apply.setVersion("1");
//        apply.setCreationDateTime(DateUtil.date());
//        apply.setDocumentId(simpleUUID);
//        apply.setMessageStatus("0");
//        apply.setBussinessNo("PXAM202533010664F00003");
//        apply.setInsuredPiccCode("CN3300210000023396");


        //报告类型（必录），1：普通；2：加急
        apply.setReportType(QuotaApplyConstants.ReportType.NORMAL);
//        apply.setCorpserialNo(OrderNumberGenerator.generate("CI"));
        apply.setNeedTranslation(QuotaApplyConstants.NeedTranslation.NO);
        apply.setCreateTime(new Date());
//        apply.setCreateUser("API");
        apply.setUpdateUser(apply.getCreateUser());
        apply.setUpdateTime(new Date());
    }


    private static void validateBaseInfo(EciCustomerQuotaApplyDTO apply, List<String> errors) {
//        ValidatorUtil.checkRequired(errors, apply.getSender(), "发送方");
//        ValidatorUtil.checkRequired(errors, apply.getReceiver(), "接收方");
//        ValidatorUtil.checkRequired(errors, apply.getCreationDateTime(), "发送时间");
//        ValidatorUtil.checkRequired(errors, apply.getMessageType(), "接口类型");
//        ValidatorUtil.checkRequired(errors, apply.getMessageStatus(), "信息状态");
//        ValidatorUtil.checkRequired(errors, apply.getVersion(), "接口版本号");
//        ValidatorUtil.checkRequired(errors, apply.getDocumentId(), "UUID");
//        ValidatorUtil.checkRequired(errors, apply.getUsageIndicator(), "UsageIndicator");

//        ValidatorUtil.checkRequired(errors, apply.getBussinessNo(), "保单号");
//        ValidatorUtil.checkRequired(errors, apply.getInsuredPiccCode(), "被保险人piccCode");

        ValidatorUtil.checkRequired(errors, apply.getOperationType(), QuotaApplyConstants.FieldName.OPERATION_TYPE);
        if (StrUtil.isNotEmpty(apply.getOperationType())) {
            if (OperationTypeEnum.NEW.getCode().equalsIgnoreCase(apply.getOperationType())) {

            } else if (OperationTypeEnum.MODIFY.getCode().equalsIgnoreCase(apply.getOperationType())) {
                ValidatorUtil.checkRequired(errors, apply.getCorpSerialNo(), QuotaApplyConstants.FieldName.CORP_SERIAL_NO);
            } else if (OperationTypeEnum.CHANGE.getCode().equalsIgnoreCase(apply.getOperationType())) {
                ValidatorUtil.checkRequired(errors, apply.getOriginalCorpSerialNo(), QuotaApplyConstants.FieldName.ORIGINAL_CORP_SERIAL_NO);
                ValidatorUtil.checkRequired(errors, apply.getChangeReasonCode(), QuotaApplyConstants.FieldName.CHANGE_REASON_CODE);

                if (StrUtil.isNotEmpty(apply.getChangeReasonCode())) {
                    ChangeReasonCodeEnum changeReasonCodeEnum = ChangeReasonCodeEnum.getByCode(apply.getChangeReasonCode());
                    if (changeReasonCodeEnum == null) {
                        errors.add(QuotaApplyConstants.ErrorMsg.CHANGE_REASON_INVALID);
                    } else {
                        if (QuotaApplyConstants.BusinessType.LC.equals(apply.getBusinessType()) && ChangeReasonCodeEnum.REASON_CODE_4.getCode().equalsIgnoreCase(apply.getChangeReasonCode())) {
                            errors.add(QuotaApplyConstants.ErrorMsg.CHANGE_REASON_LC_NOT_ALLOWED);
                        }
                    }
                }
            } else {
                errors.add(QuotaApplyConstants.ErrorMsg.OPERATION_TYPE_MISMATCH);
            }
        }
    }

    private static void validateBuyerInfo(EciCustomerQuotaApplyDTO apply, List<String> errors) {
        ValidatorUtil.checkRequired(errors, apply.getRiskCompName(), QuotaApplyConstants.FieldName.RISK_COMP_NAME);
        ValidatorUtil.checkRequired(errors, apply.getCountryOrArea(), QuotaApplyConstants.FieldName.COUNTRY_OR_AREA);
        ValidatorUtil.checkRequired(errors, apply.getRiskCompAddress(), QuotaApplyConstants.FieldName.RISK_COMP_ADDRESS);
        ValidatorUtil.checkRequired(errors, apply.getRiskMark(), QuotaApplyConstants.FieldName.RISK_MARK);
        ValidatorUtil.checkRequired(errors, apply.getCreateUser(), QuotaApplyConstants.FieldName.CREATE_USER);

        if (StrUtil.isNotEmpty(apply.getCountryOrArea())) {
            CountryEnum countryEnum = CountryEnum.getByCode(apply.getCountryOrArea());
            // 国家/地区校验
            if (countryEnum == null) {
                errors.add(QuotaApplyConstants.ErrorMsg.COUNTRY_INVALID);
            }
        }

        // 条件必填：当买方国家和地区为CHN时，省份必填
        if (CountryEnum.CHN.getCode().equalsIgnoreCase(apply.getCountryOrArea())) {
            ValidatorUtil.checkRequired(errors, apply.getProvince(), QuotaApplyConstants.FieldName.PROVINCE);
            if (StrUtil.isNotEmpty(apply.getProvince())) {
                ProvinceEnum provinceEnum = ProvinceEnum.getByCode(apply.getProvince());
                if (provinceEnum == null) {
                    errors.add(QuotaApplyConstants.ErrorMsg.PROVINCE_INVALID);
                }
            }
        }
    }

    private static void validateQuotaInfo(EciCustomerQuotaApplyDTO apply, List<String> errors) {
        ValidatorUtil.checkRequired(errors, apply.getPaidTerm(), QuotaApplyConstants.FieldName.PAID_TERM);
        ValidatorUtil.checkRequired(errors, apply.getAppliAmount(), QuotaApplyConstants.FieldName.APPLI_AMOUNT);
        ValidatorUtil.checkRequired(errors, apply.getReportType(), QuotaApplyConstants.FieldName.REPORT_TYPE);

        // 报告类型值校验
        if (apply.getReportType() != null &&
                !QuotaApplyConstants.ReportType.NORMAL.equals(apply.getReportType()) &&
                !QuotaApplyConstants.ReportType.URGENT.equals(apply.getReportType())) {
            errors.add(QuotaApplyConstants.ErrorMsg.REPORT_TYPE_INVALID);
        }

        ValidatorUtil.checkRequired(errors, apply.getExportTrade(), QuotaApplyConstants.FieldName.EXPORT_TRADE);
        if (StrUtil.isNotEmpty(apply.getExportTrade())) {
            ProductCategoryEnum productCategoryEnum = ProductCategoryEnum.getByCode(apply.getExportTrade());
            if (productCategoryEnum == null) {
                errors.add(QuotaApplyConstants.ErrorMsg.PRODUCT_CATEGORY_INVALID);
            }
        }
        // 当商品类别选择"其他"时，说明必填
        if (ProductCategoryEnum.OTHER.getCode().equalsIgnoreCase(apply.getExportTrade())) {
            ValidatorUtil.checkRequired(errors, apply.getExportTradeInput(), QuotaApplyConstants.FieldName.EXPORT_TRADE_INPUT);
        } else {
            apply.setExportTradeInput(null);
        }
    }

    private static void validateLcInfo(EciCustomerQuotaApplyDTO apply, List<String> errors) {
        ValidatorUtil.checkRequired(errors, apply.getCreditNo(), QuotaApplyConstants.FieldName.CREDIT_NO);
        ValidatorUtil.checkRequired(errors, apply.getIsCycleUse(), QuotaApplyConstants.FieldName.IS_CYCLE_USE);
        ValidatorUtil.checkRequired(errors, apply.getBankName(), QuotaApplyConstants.FieldName.BANK_NAME);
        ValidatorUtil.checkRequired(errors, apply.getBankCountry(), QuotaApplyConstants.FieldName.BANK_COUNTRY);
        ValidatorUtil.checkRequired(errors, apply.getBankSwift(), QuotaApplyConstants.FieldName.BANK_SWIFT);
        ValidatorUtil.checkRequired(errors, apply.getBankAddress(), QuotaApplyConstants.FieldName.BANK_ADDRESS);
        ValidatorUtil.checkRequired(errors, apply.getExportComName(), QuotaApplyConstants.FieldName.EXPORT_COM_NAME);
        ValidatorUtil.checkRequired(errors, apply.getIsBatch(), QuotaApplyConstants.FieldName.IS_BATCH);

        // 循环使用值校验
        if (apply.getIsCycleUse() != null &&
                !QuotaApplyConstants.CycleUse.NO.equals(apply.getIsCycleUse()) &&
                !QuotaApplyConstants.CycleUse.YES.equals(apply.getIsCycleUse())) {
            errors.add(QuotaApplyConstants.ErrorMsg.CYCLE_USE_INVALID);
        }

        // 分批处理逻辑
        if (QuotaApplyConstants.IsBatch.YES.equals(apply.getIsBatch())) {
            // 第一批金额为必填
            ValidatorUtil.checkRequired(errors, apply.getMaxAmount1(), QuotaApplyConstants.FieldName.MAX_AMOUNT1);
            // 第二批金额为必填
            ValidatorUtil.checkRequired(errors, apply.getMaxAmount2(), QuotaApplyConstants.FieldName.MAX_AMOUNT2);

        } else {
            apply.setMaxAmount1(null);
            apply.setMaxAmount2(null);

        }
    }

    private static void validateTransactionHistory(EciCustomerQuotaApplyDTO apply, List<String> errors) {

        //无历史交易时 数据清空
        if (QuotaApplyConstants.HistoryBusiness.NO.equals(apply.getHistoryBusiness())) {
            //
            apply.setEarlyDealYear(null);
            apply.setBankPerformance(null);
            apply.setRiskPerformance(null);
            apply.setTransactionLc(null);
            apply.setTransactionDp(null);
            apply.setTransactionDa(null);
            apply.setIsDefaultThis(QuotaApplyConstants.IsDefault.NO);
            apply.setDefaultAmount(null);
            apply.setDefaultDate(null);
        }

        if (!QuotaApplyConstants.HistoryBusiness.YES.equals(apply.getHistoryBusiness())) {
            return; // 无历史交易时不校验
        }

        // 外贸历史交易校验
        if (QuotaApplyConstants.BusinessType.LC.equals(apply.getBusinessType()) || QuotaApplyConstants.BusinessType.NON_LC.equals(apply.getBusinessType())) {
            ValidatorUtil.checkRequired(errors, apply.getEarlyDealYear(), QuotaApplyConstants.FieldName.EARLY_DEAL_YEAR);

            // 信用证业务下银行付款表现必填
            if (QuotaApplyConstants.BusinessType.LC.equals(apply.getBusinessType())) {
                ValidatorUtil.checkRequired(errors, apply.getBankPerformance(), QuotaApplyConstants.FieldName.BANK_PERFORMANCE);
            }

            ValidatorUtil.checkRequired(errors, apply.getRiskPerformance(), QuotaApplyConstants.FieldName.RISK_PERFORMANCE);

            // 三项交易金额至少填一项
            boolean hasTransaction = apply.getTransactionLc() != null ||
                    apply.getTransactionDp() != null ||
                    apply.getTransactionDa() != null;
            if (!hasTransaction) {
                errors.add(QuotaApplyConstants.ErrorMsg.BATCH_REQUIRED);
            }

            ValidatorUtil.checkRequired(errors, apply.getIsDefaultThis(), QuotaApplyConstants.FieldName.IS_DEFAULT_THIS);

            // 有拖欠时必填金额和时间
            if (QuotaApplyConstants.IsDefault.YES.equalsIgnoreCase(apply.getIsDefaultThis())) {
                ValidatorUtil.checkRequired(errors, apply.getDefaultAmount(), QuotaApplyConstants.FieldName.DEFAULT_AMOUNT);
                ValidatorUtil.checkRequired(errors, apply.getDefaultDate(), QuotaApplyConstants.FieldName.DEFAULT_DATE);
            }
        }
    }

    private static void validateBusinessInfo(EciCustomerQuotaApplyDTO apply, List<String> errors) {


        // 非信用证业务时
        if (QuotaApplyConstants.BusinessType.NON_LC.equals(apply.getBusinessType())) {
            ValidatorUtil.checkRequired(errors, apply.getExportName(), QuotaApplyConstants.FieldName.EXPORT_NAME);
            ValidatorUtil.checkRequired(errors, apply.getNeedTranslation(), QuotaApplyConstants.FieldName.NEED_TRANSLATION);
            // 翻译件值校验
            if (apply.getNeedTranslation() != null &&
                    !QuotaApplyConstants.NeedTranslation.NO.equals(apply.getNeedTranslation()) &&
                    !QuotaApplyConstants.NeedTranslation.YES.equals(apply.getNeedTranslation())) {
                errors.add(QuotaApplyConstants.ErrorMsg.TRANSLATION_INVALID);
            }
        }

        // 支付方式校验
        ValidatorUtil.checkRequired(errors, apply.getPayWay(), QuotaApplyConstants.FieldName.PAY_WAY);
        if (apply.getPayWay() != null) {
            if (QuotaApplyConstants.BusinessType.LC.equals(apply.getBusinessType())) {
                if (!QuotaApplyConstants.BusinessType.LC.equals(apply.getPayWay())) {
                    errors.add(QuotaApplyConstants.ErrorMsg.LC_PAYWAY_INVALID);
                }
            } else {
                if (!"DP".equals(apply.getPayWay()) &&
                        !"DA".equals(apply.getPayWay()) &&
                        !"OA".equals(apply.getPayWay())) {
                    errors.add(QuotaApplyConstants.ErrorMsg.NON_LC_PAYWAY_INVALID);
                }
            }
        }
    }

    private static void validateFieldLengths(EciCustomerQuotaApplyDTO apply, List<String> errors) {
        // 字符串字段长度校验
        ValidatorUtil.checkMaxLength(errors, apply.getRiskCompName(), 600, "买方名称");
        ValidatorUtil.checkMaxLength(errors, apply.getCountryOrArea(), 50, "买方国家和地区");
        ValidatorUtil.checkMaxLength(errors, apply.getRiskCompAddress(), 300, "买方地址");
        ValidatorUtil.checkMaxLength(errors, apply.getProvince(), 12, "买方所属省份");
        ValidatorUtil.checkMaxLength(errors, apply.getRiskPhone(), 50, "买方联系电话");
        ValidatorUtil.checkMaxLength(errors, apply.getRiskMark(), 100, "买方注册号");
        ValidatorUtil.checkMaxLength(errors, apply.getCreditNo(), 50, "信用证号");
        ValidatorUtil.checkMaxLength(errors, apply.getBankName(), 150, "开证行名称");
        ValidatorUtil.checkMaxLength(errors, apply.getBankCountry(), 50, "开证行国家和地区");
        ValidatorUtil.checkMaxLength(errors, apply.getBankSwift(), 50, "开证行SWIFT");
        ValidatorUtil.checkMaxLength(errors, apply.getBankAddress(), 200, "开证行地址");
        ValidatorUtil.checkMaxLength(errors, apply.getExportComName(), 100, "出口商品名称");
        ValidatorUtil.checkMaxLength(errors, apply.getExportTrade(), 200, "商品类别");
        ValidatorUtil.checkMaxLength(errors, apply.getExportTradeInput(), 40, "商品类别说明");
        ValidatorUtil.checkMaxLength(errors, apply.getTransType(), 10, "运输方式");
        ValidatorUtil.checkMaxLength(errors, apply.getEarlyDealYear(), 50, "最早成交年份");
        ValidatorUtil.checkMaxLength(errors, apply.getBankPerformance(), 10, "银行付款表现");
        ValidatorUtil.checkMaxLength(errors, apply.getRiskPerformance(), 10, "买方付款表现");
        ValidatorUtil.checkMaxLength(errors, apply.getStartYear(), 50, "开始放账年份");
        ValidatorUtil.checkMaxLength(errors, apply.getRemark(), 1500, "备注");
        ValidatorUtil.checkMaxLength(errors, apply.getChangeReasonCode(), 12, "限额变更原因");
        ValidatorUtil.checkMaxLength(errors, apply.getChangeReasonRemark(), 500, "逾期未回款原因说明");
        ValidatorUtil.checkMaxLength(errors, apply.getExportName(), 100, "出口商品名称(非LC)");
        ValidatorUtil.checkMaxLength(errors, apply.getPayWay(), 50, "支付方式");
        ValidatorUtil.checkMaxLength(errors, apply.getCorpSerialNo(), 50, "系统流水号");
//        ValidatorUtil.checkMaxLength(errors, apply.getBussinessNo(), 22, "保单号");
//        ValidatorUtil.checkMaxLength(errors, apply.getInsuredPiccCode(), 44, "被保险人piccCode");
    }


}
